const Message = require('../models/Message');
const User = require('../models/User');
const friendService = require('../services/friendService');

// @desc    发送消息
// @route   POST /api/messages
// @access  Private
const sendMessage = async (req, res) => {
  try {
    console.log('接收到消息发送请求:', req.body);
    const { receiverId, content, type = 'text' } = req.body;
    const receiver = receiverId; // 添加映射，兼容前端发送的receiverId参数
    
    if (!content || !receiver) {
      console.error('消息发送失败: 缺少必要参数');
      return res.status(400).json({ message: '接收者和内容不能为空' });
    }

    // 验证接收者是否存在
    const receiverUser = await User.findById(receiver);
    if (!receiverUser) {
      console.error('消息发送失败: 接收者不存在', receiver);
      return res.status(404).json({ message: '接收者不存在' });
    }

    // 使用friendService验证是否是好友
    console.log('检查好友关系:', req.user._id.toString(), receiver);
    const isFriend = await friendService.checkFriendship(req.user._id.toString(), receiver);
    console.log('好友关系检查结果:', isFriend);
    
    if (!isFriend) {
      console.error('消息发送失败: 非好友关系');
      return res.status(403).json({ message: '只能给好友发送消息' });
    }

    // 检查是否是短时间内的重复消息(1分钟内相同内容)
    const now = new Date();
    const oneMinuteAgo = new Date(now.getTime() - 60 * 1000);

    const recentDuplicates = await Message.find({
      sender: req.user._id,
      receiver: receiver,
      content: content,
      createdAt: { $gte: oneMinuteAgo }
    });

    if (recentDuplicates.length > 0) {
      console.log('检测到短时间内重复消息，忽略创建新消息');
      
      // 返回最近的消息，避免前端出错
      const existingMessage = await recentDuplicates[0].populate('sender', 'username avatar');
      await existingMessage.populate('receiver', 'username avatar');
      
      return res.status(200).json(existingMessage);
    }

    // 创建消息
    console.log('创建消息记录...');
    const message = await Message.create({
      sender: req.user._id,
      receiver,
      content,
      type
    });

    // 关联发送者和接收者信息
    await message.populate('sender', 'username avatar');
    await message.populate('receiver', 'username avatar');
    
    console.log('消息发送成功:', message._id);
    res.status(201).json(message);
  } catch (error) {
    console.error('消息发送失败:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

// @desc    获取与特定用户的聊天记录
// @route   GET /api/messages/:userId
// @access  Private
const getMessagesByUser = async (req, res) => {
  try {
    const { userId } = req.params;
    const currentUserId = req.user._id;

    // 验证目标用户是否存在
    const targetUser = await User.findById(userId);
    if (!targetUser) {
      return res.status(404).json({ message: '用户不存在' });
    }

    // 验证是否是好友关系，只有好友才能查看聊天记录
    const isFriend = await friendService.checkFriendship(currentUserId.toString(), userId);
    if (!isFriend) {
      return res.status(403).json({ message: '只能查看与好友的聊天记录' });
    }

    // 获取双向消息
    const messages = await Message.find({
      $or: [
        { sender: currentUserId, receiver: userId },
        { sender: userId, receiver: currentUserId }
      ]
    })
      .sort({ createdAt: 1 })
      .populate('sender', 'username avatar')
      .populate('receiver', 'username avatar');

    // 将当前用户收到的未读消息标记为已读
    await Message.updateMany(
      { sender: userId, receiver: currentUserId, read: false },
      { read: true }
    );

    // 添加消息去重逻辑
    const uniqueMessages = new Map();
    const filteredMessages = [];
    
    // 遍历消息，使用消息内容+时间戳作为去重键
    messages.forEach(message => {
      // 创建唯一键 - 使用内容+发送者+接收者+时间戳(精确到分钟)的组合
      const date = new Date(message.createdAt);
      const timeKey = `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}-${date.getHours()}-${date.getMinutes()}`;
      const uniqueKey = `${message.content}_${message.sender._id}_${message.receiver._id}_${timeKey}`;
      
      // 如果这个键不存在，添加消息到结果集
      if (!uniqueMessages.has(uniqueKey)) {
        uniqueMessages.set(uniqueKey, true);
        filteredMessages.push(message);
      } else {
        console.log(`检测到重复消息，内容: "${message.content}", ID: ${message._id}`);
      }
    });

    console.log(`原始消息数量: ${messages.length}, 去重后消息数量: ${filteredMessages.length}`);
    res.json(filteredMessages);
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: '服务器错误' });
  }
};

// @desc    获取最近的聊天会话
// @route   GET /api/messages/chats/recent
// @access  Private
const getRecentChats = async (req, res) => {
  try {
    const currentUserId = req.user._id;

    // 获取当前用户的好友列表，确保只展示好友聊天
    const friendIds = await friendService.getUserFriendsIds(currentUserId.toString());
    
    // 查找当前用户的所有私人消息，仅限于好友之间的消息
    const messages = await Message.find({
      $or: [
        // 当前用户发送给好友的消息
        { 
          sender: currentUserId, 
          receiver: { $in: friendIds },
          target_type: { $ne: 'group' }
        },
        // 好友发送给当前用户的消息
        { 
          sender: { $in: friendIds }, 
          receiver: currentUserId,
          target_type: { $ne: 'group' }
        }
      ]
    })
      .sort({ createdAt: -1 })
      .populate('sender', 'username avatar')
      .populate('receiver', 'username avatar');

    // 获取唯一的对话伙伴集合（私聊）
    const chatPartners = new Map();

    // 用于去重未读消息的集合
    const processedUnreadMessages = new Set();

    // 处理私聊消息
    messages.forEach(message => {
      try {
        const partnerId = message.sender._id.toString() === currentUserId.toString()
          ? message.receiver._id.toString()
          : message.sender._id.toString();
        
        if (!chatPartners.has(partnerId)) {
          const partner = message.sender._id.toString() === currentUserId.toString()
            ? message.receiver
            : message.sender;
          
          // 获取未读消息数量 - 添加去重处理
          const unreadMessages = messages.filter(m => 
            m.sender._id.toString() === partnerId && 
            m.receiver._id.toString() === currentUserId.toString() && 
            !m.read
          );
          
          // 使用Set进行消息去重（按内容+时间戳的分钟级别）
          let uniqueUnreadCount = 0;
          unreadMessages.forEach(msg => {
            const date = new Date(msg.createdAt);
            const timeKey = `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}-${date.getHours()}-${date.getMinutes()}`;
            const uniqueKey = `${msg.content}_${msg.sender._id}_${msg.receiver._id}_${timeKey}`;
            
            if (!processedUnreadMessages.has(uniqueKey)) {
              processedUnreadMessages.add(uniqueKey);
              uniqueUnreadCount++;
            }
          });

          chatPartners.set(partnerId, {
            _id: partner._id,
            username: partner.username,
            avatar: partner.avatar,
            lastMessage: {
              content: message.content,
              type: message.type,
              createdAt: message.createdAt
            },
            unreadCount: uniqueUnreadCount,
            isGroup: false // 标记为私聊
          });
        }
      } catch (err) {
        console.error('处理私聊消息出错:', err);
      }
    });

    // 查询用户参与的群组
    const { query } = require('../config/mysqlConfig');
    const userGroups = await query(
      `SELECT g.*, 
        (SELECT COUNT(*) FROM group_members WHERE group_id = g.id) as member_count
       FROM \`groups\` g
       JOIN group_members gm ON g.id = gm.group_id
       WHERE gm.user_id = ?`,
      [currentUserId.toString()]
    );

    // 为每个群组获取最后一条消息和未读消息数
    for (const group of userGroups) {
      try {
        // 获取群组最后一条消息
        const lastGroupMessage = await Message.findOne({
          group_id: group.id,
          target_type: 'group'
        })
        .sort({ createdAt: -1 })
        .populate('sender', 'username');
        
        // 计算未读消息数
        const unreadCount = await Message.countDocuments({
          group_id: group.id,
          target_type: 'group',
          sender: { $ne: currentUserId },
          read_by: { $ne: currentUserId }
        });

        // 添加到聊天列表中
        if (lastGroupMessage) {
          chatPartners.set(`group_${group.id}`, {
            _id: `group_${group.id}`,
            username: group.name,
            avatar: group.group_avatar || '👥',
            lastMessage: {
              content: lastGroupMessage ? lastGroupMessage.content : '暂无消息',
              type: lastGroupMessage ? lastGroupMessage.type : 'text',
              createdAt: lastGroupMessage ? lastGroupMessage.createdAt : group.created_at
            },
            unreadCount: unreadCount,
            isGroup: true, // 标记为群聊
            memberCount: group.member_count
          });
        } else {
          // 没有消息的群组也应该显示
          chatPartners.set(`group_${group.id}`, {
            _id: `group_${group.id}`,
            username: group.name,
            avatar: group.group_avatar || '👥',
            lastMessage: {
              content: '暂无消息',
              type: 'text',
              createdAt: group.created_at
            },
            unreadCount: 0,
            isGroup: true, // 标记为群聊
            memberCount: group.member_count
          });
        }
      } catch (err) {
        console.error(`获取群组 ${group.id} 信息出错:`, err);
      }
    }

    console.log("获取聊天列表，未读消息详情:", 
      Array.from(chatPartners.values()).map(chat => 
        `${chat.username}${chat.isGroup ? '(群聊)' : ''}: ${chat.unreadCount}条未读`
      )
    );

    res.json(Array.from(chatPartners.values()));
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: '服务器错误' });
  }
};

// @desc    搜索与特定用户的聊天记录
// @route   GET /api/messages/:userId/search
// @access  Private
const searchMessages = async (req, res) => {
  try {
    const { userId } = req.params;
    const { keyword } = req.query;
    const currentUserId = req.user._id;

    if (!keyword) {
      return res.status(400).json({ message: '请提供搜索关键词' });
    }

    // 验证目标用户是否存在
    const targetUser = await User.findById(userId);
    if (!targetUser) {
      return res.status(404).json({ message: '用户不存在' });
    }

    console.log(`搜索消息: 用户 ${currentUserId} 正在搜索与 ${userId} 的聊天记录，关键词: "${keyword}"`);

    try {
      // 安全地创建正则表达式
      const searchRegex = new RegExp(keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i');
      
      // 搜索双向消息
      const messages = await Message.find({
        $or: [
          { sender: currentUserId, receiver: userId },
          { sender: userId, receiver: currentUserId }
        ],
        content: { $regex: searchRegex }
      })
        .sort({ createdAt: -1 })
        .populate('sender', 'username avatar')
        .populate('receiver', 'username avatar');

      console.log(`搜索结果: 找到 ${messages.length} 条消息`);
      res.json(messages);
    } catch (regexError) {
      console.error('正则表达式错误:', regexError);
      return res.status(400).json({ message: '搜索关键词无效' });
    }
  } catch (error) {
    console.error('搜索消息失败:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

// @desc    标记与特定用户的消息为已读
// @route   PUT /api/messages/:userId/read
// @access  Private
const markMessagesAsRead = async (req, res) => {
  try {
    const { userId } = req.params;
    const currentUserId = req.user._id;

    // 标记从指定用户收到的所有未读消息为已读
    const result = await Message.updateMany(
      { sender: userId, receiver: currentUserId, read: false },
      { read: true }
    );

    console.log(`已将${result.modifiedCount}条消息标记为已读`);
    
    res.json({ 
      success: true, 
      markedCount: result.modifiedCount 
    });
  } catch (error) {
    console.error('标记消息已读失败:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

module.exports = {
  sendMessage,
  getMessagesByUser,
  getRecentChats,
  searchMessages,
  markMessagesAsRead
}; 